#ifndef B2D_IRESOURCE_H
#define B2D_IRESOURCE_H

#include "Object.h"
#include "StringId.h"
#include "Stream.h"

NS_B2D_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief	Interface for a resource.
/// 		Resource types must be marked with the macro B2D_OBJECT
////////////////////////////////////////////////////////////////////////////////////////////////////
class B2D_API IResource
	: public Object
	, public IUncopyable
{
	B2D_INTERFACE(IResource)
	B2D_OBJECT

public:
	typedef string Tag;

public:
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Gets resource type. This may be different from the object type since for example
	/// 		GLTexture : ObjectType(GLTexture), ResourceType(ITexture)
	///
	/// \return	The resource type.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual const ObjectType& getResourceType(void) const = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Get unique name of the resource. If this resource has been loaded from a file, the
	/// 		name will be the path to the file.
	///
	/// \return	The name.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual const StringId& getName(void) const = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Sets the name of the resource. If this resource is being managed by the resource
	/// 		manager, the manager will keep the old new unless the resource is unregistered and
	/// 		registered again. Its not a good idea to change the name of managed resources anyway
	/// 		as it can lead to duplicated resources.
	///
	/// \param	name	The name.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual void setName(const StringId& name) = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Gets the tag.
	///
	/// \return	The tag.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual const Tag& getTag(void) const = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Sets the tag.
	///
	/// \param	tag	The tag value.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual void setTag(const Tag& tag) = 0;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Gets size estimate of the resource.
	///
	/// \return	The size estimate.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual size_t getSizeEstimate(void) const = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Loads the given (file)stream.
	///
	/// \param	stream	The stream to load from.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual void load(const StreamPtr& stream) = 0;
};

typedef std::shared_ptr<IResource> ResourcePtr;

#define B2D_RESOURCE B2D_OBJECT \
	const static ObjectType ResourceType; \
	const ObjectType& getResourceType(void) const { return ResourceType; }
#define B2D_RESOURCE_IMPL(type, base) B2D_OBJECT_IMPL(type, base) \
	const ObjectType type::ResourceType = ObjectType::create<type,base>();

NS_B2D_END

#endif